<template>
  <div id="exref">
    <button v-on:click="changeMsg">{{ message }}</button>
    <button @click="fn">{{ obj1.name }}</button>
    <button @click="fn2">{{mystr}}</button>
  </div>
</template>


<script setup lang="ts">
import { ref, Ref, isRef, shallowRef, triggerRef, customRef } from 'vue'

// 使用ref包裹可以使数据变为响应式的
let message: Ref<string> = ref("阿夸")
let name: string = 'Jack'
const changeMsg = () => {
  // 访问数据通过.value的方式访问
  message.value = '小杜'
  // 通过isRef可以判断一个数据是不是Ref对象
  console.log(isRef(name));
}

// shallowRef声明的对象不是响应式的
const obj1 = shallowRef({
  name: 'Tom'
})
const fn = () => {
  // name被改变了，但是视图没有变化
  obj1.value.name = 'aaa'
  console.log(obj1.value);
  // 使用triggerRef可以让视图强制更新
  triggerRef(obj1)
}

// customRef对ref数据进行一些自定义的操作
// 定义一个函数，返回一个customRef对象
function myRef<T>(value: T) {
  // customRef接收一个工厂函数，接收两个参数，返回一个对象
  return customRef((trank, trigger) => {
    // 对象里面必须包含get和set方法
    return {
      // 对象实例被访问时调用get方法
      get() {
        console.log('get');
        trank()
        return value
      },
      // 被修改时调用set方法
      set(newValue: T) {
        console.log('set');
        value = newValue
        trigger()
      }
    }
  })
}
let mystr = myRef<string>('自定义ref')
const fn2 = () => { 
  mystr.value = 'AAAA'
 }

</script>

<style lang="less">
</style>
